﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace Tuxedo.Compile
{
	internal class VariableDeclaration : CodeLine
	{
		public UnverifiedType Type { get; private set; }
		public string[] VariableNames { get; private set; }
		public Expression[] DefaultValue { get; private set; } // null indicates default value for that type

		public VariableDeclaration(UnverifiedType type, IList<string> variableNames, IList<Expression> startingValues)
		{
			this.Type = type;
			this.VariableNames = variableNames.ToArray();
			this.DefaultValue = startingValues.ToArray();
		}

		public static VariableDeclaration Parse(TokenStream tokens, bool failSilently)
		{
			int tokenIndex = tokens.GetCurrentIndex();
			UnverifiedType type = UnverifiedType.Parse(tokens, true);
			if (type == null)
			{
				if (failSilently)
				{
					tokens.RestoreIndex(tokenIndex);
					return null;
				}
				throw new Exception("A type was expected here.");
			}

			List<string> variables = new List<string>();
			List<Expression> startingValues = new List<Expression>();

			while (true)
			{
				string variableName = tokens.PopIdentifier(true);
				if (variableName == null)
				{
					if (failSilently)
					{
						tokens.RestoreIndex(tokenIndex);
						return null;
					}
					throw new Exception("Bad variable declaration");
				}
				variables.Add(variableName);
				Expression startingValue = null;
				if (tokens.PopIfPresent("="))
				{
					startingValue = Expression.ParseExpression(tokens);
				}
				startingValues.Add(startingValue);
				
				if (tokens.PopIfPresent(","))
				{
					// there is another!
				}
				else if (tokens.PopIfPresent(";"))
				{
					break;
				}
				else
				{
					if (failSilently)
					{
						tokens.RestoreIndex(tokenIndex);
						return null;
					}
					throw new Exception("Bad variable declaration");
				}
			}

			return new VariableDeclaration(type, variables, startingValues);
		}
	}
}
